package com.aipartner.service.impl;

import com.aipartner.config.AiModelConfig;
import com.aipartner.dto.ChatRequest;
import com.aipartner.dto.ChatResponse;
import com.aipartner.entity.ChatHistory;
import com.aipartner.mapper.ChatHistoryMapper;
import com.aipartner.service.AiService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

/**
 * AI Service Implementation
 * 
 * @author AI Partner Team
 * @since 2024-01-20
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class AiServiceImpl implements AiService {
    
    private final ChatHistoryMapper chatHistoryMapper;
    private final AiModelConfig aiModelConfig;
    private final WebClient webClient;
    
    @Override
    public ChatResponse chat(ChatRequest request) {
        try {
            // 优先使用前端指定的模型，如果没有指定则根据功能类型确定
            String functionId = request.getChatType();
            String selectedModelId;
            
            if (request.getModelType() != null && !request.getModelType().isEmpty()) {
                // 使用前端指定的模型
                selectedModelId = request.getModelType();
                log.info("Using user specified model: {}", selectedModelId);
            } else {
                // 根据功能类型自动确定模型
                selectedModelId = determineModelForFunction(functionId);
                log.info("Auto-selected model for function {}: {}", functionId, selectedModelId);
            }
            
            log.info("Processing chat request for user: {}, function: {}, selected model: {}", 
                    request.getUserId(), functionId, selectedModelId);
            
            String response;
            if (aiModelConfig.isModelAvailable(selectedModelId)) {
                response = callExternalModel(request.getMessage(), selectedModelId);
                if (response == null || response.isEmpty()) {
                    response = generateFunctionResponse(request.getMessage(), functionId,
                            aiModelConfig.getModel(selectedModelId) != null ? aiModelConfig.getModel(selectedModelId).getName() : selectedModelId);
                }
            } else {
                response = generateFunctionResponse(request.getMessage(), functionId,
                        aiModelConfig.getModel(selectedModelId) != null ? aiModelConfig.getModel(selectedModelId).getName() : selectedModelId);
            }
            
            ChatHistory history = new ChatHistory();
            history.setUserId(request.getUserId());
            // session_id、cost、error_message 在 schema 中无对应列，跳过
            history.setModelName(selectedModelId);
            history.setFunctionType(request.getChatType()); // 对应 function_category
            history.setFunctionName(request.getChatType());
            history.setUserMessage(request.getMessage());
            history.setAiResponse(response);
            history.setTokensUsed(estimateTokens(request.getMessage() + response)); // 对应 token_used
            history.setResponseTime(500L + new Random().nextInt(1000)); // 对应 processing_time
            history.setStatus(1);
            
            chatHistoryMapper.insert(history);
            
            ChatResponse chatResponse = new ChatResponse();
            chatResponse.setReply(response);
            chatResponse.setMessageId(String.valueOf(history.getId()));
            chatResponse.setConversationId(request.getConversationId());
            chatResponse.setModelType(selectedModelId);
            chatResponse.setTimestamp(LocalDateTime.now());
            chatResponse.setTokenUsage(history.getTokensUsed());
            
            return chatResponse;
            
        } catch (Exception e) {
            log.error("Chat processing failed", e);
            throw new RuntimeException("AI service error: " + e.getMessage());
        }
    }
    
    /**
     * 根据功能ID确定使用的AI模型
     */
    private String determineModelForFunction(String functionId) {
        if (functionId == null) {
            return aiModelConfig.getDefaultModel();
        }
        
        String modelId = aiModelConfig.getModelForFunction(functionId);
        
        // 检查模型是否可用，如果不可用则使用默认模型
        if (!aiModelConfig.isModelAvailable(modelId)) {
            log.warn("Model {} is not available for function {}, using default model", modelId, functionId);
            modelId = aiModelConfig.getDefaultModel();
        }
        
        return modelId;
    }
    
    /**
     * 优先调用外部模型（如 DeepSeek/OpenAI 兼容接口），失败时上层回退到模板响应
     */
    private String callExternalModel(String userMessage, String modelId) {
        try {
        AiModelConfig.AiModel model = aiModelConfig.getModel(modelId);
            if (model == null || model.getApiUrl() == null || model.getApiKey() == null) {
                return null;
            }

            JSONObject payload = new JSONObject();
            // 优先使用配置中的 modelName，如果没有则使用 modelId
            String requestModel = model.getModelName() != null ? model.getModelName() : modelId;
            String apiUrl = model.getApiUrl();
            
            // DeepSeek 兼容处理：如果没有指定 modelName 且是 DeepSeek API，使用 deepseek-chat
            if (model.getModelName() == null && apiUrl != null && apiUrl.contains("deepseek.com")) {
                requestModel = "deepseek-chat";
            }
            
            payload.put("model", requestModel);
            JSONArray messages = new JSONArray();
            JSONObject userMsg = new JSONObject();
            userMsg.put("role", "user");
            userMsg.put("content", userMessage);
            messages.add(userMsg);
            payload.put("messages", messages);
            payload.put("temperature", 0.7);
            payload.put("stream", false);
            payload.put("max_tokens", 1024);

            // 添加请求调试信息
            log.info("Making API call to model {}: URL={}, Model={}", modelId, model.getApiUrl(), requestModel);
            log.info("Request payload: {}", payload.toJSONString());

            // 根据不同的API提供商设置不同的认证方式
            WebClient.RequestBodySpec request = webClient.post()
                    .uri(model.getApiUrl())
                    .header("Content-Type", "application/json");
            
            // 豆包API使用不同的认证方式
            if (apiUrl != null && apiUrl.contains("volces.com")) {
                // 豆包API使用 Authorization: Bearer 格式，但key可能需要解码
                String apiKey = model.getApiKey();
                // 如果是Base64编码的key，先解码
                try {
                    String decodedKey = new String(java.util.Base64.getDecoder().decode(apiKey));
                    log.info("Using decoded API key for Doubao: {}", decodedKey.substring(0, Math.min(10, decodedKey.length())) + "...");
                    request = request.header("Authorization", "Bearer " + decodedKey);
                } catch (Exception e) {
                    // 如果解码失败，直接使用原key
                    log.info("Using original API key for Doubao (decode failed): {}", apiKey.substring(0, Math.min(10, apiKey.length())) + "...");
                    request = request.header("Authorization", "Bearer " + apiKey);
                }
            } else {
                // 其他API使用标准Bearer认证
                request = request.header("Authorization", "Bearer " + model.getApiKey());
            }

            String raw = request
                    .bodyValue(payload.toJSONString())
                    .retrieve()
                    .onStatus(status -> !status.is2xxSuccessful(), clientResponse ->
                            clientResponse.bodyToMono(String.class)
                                    .defaultIfEmpty("")
                                    .map(body -> new RuntimeException("HTTP " + clientResponse.statusCode().value() + ": " + body))
                    )
                    .bodyToMono(String.class)
                    .timeout(java.time.Duration.ofSeconds(110))
                    .block();

            if (raw == null || raw.isEmpty()) {
                return null;
            }

            // 添加详细的API响应日志用于调试
            log.info("API Response for model {}: {}", modelId, raw);

            JSONObject obj = JSON.parseObject(raw);
            
            // 标准OpenAI格式：choices[0].message.content
            JSONArray choices = obj.getJSONArray("choices");
            if (choices != null && !choices.isEmpty()) {
                JSONObject first = choices.getJSONObject(0);
                if (first != null) {
                    JSONObject message = first.getJSONObject("message");
                    if (message != null) {
                        String content = message.getString("content");
                        if (content != null && !content.isEmpty()) {
                            log.info("Extracted content from choices[0].message.content: {}", content);
                            return content.trim();
                        }
                    }
                    
                    // 备选格式：choices[0].text
                    String text = first.getString("text");
                    if (text != null && !text.isEmpty()) {
                        log.info("Extracted content from choices[0].text: {}", text);
                        return text.trim();
                    }
                    
                    // 备选格式：choices[0].delta.content (流式响应格式)
                    JSONObject delta = first.getJSONObject("delta");
                    if (delta != null) {
                        String deltaContent = delta.getString("content");
                        if (deltaContent != null && !deltaContent.isEmpty()) {
                            log.info("Extracted content from choices[0].delta.content: {}", deltaContent);
                            return deltaContent.trim();
                        }
                    }
                }
            }
            
            // 兼容其他可能的响应格式
            String content = obj.getString("content");
            if (content != null && !content.isEmpty()) {
                log.info("Extracted content from root.content: {}", content);
                return content.trim();
            }
            
            // 兼容 data 字段
            JSONObject data = obj.getJSONObject("data");
            if (data != null) {
                String dataContent = data.getString("content");
                if (dataContent != null && !dataContent.isEmpty()) {
                    log.info("Extracted content from data.content: {}", dataContent);
                    return dataContent.trim();
                }
            }
            
            log.warn("Could not extract content from API response for model {}: {}", modelId, raw);
            return null;
        } catch (Exception e) {
            log.error("External model call failed for {}: {}", modelId, e.getMessage(), e);
            return null;
        }
    }
    
    private String generateFunctionResponse(String userMessage, String functionId, String modelName) {
        String baseResponse = getFunctionBaseResponse(functionId, userMessage);
        return baseResponse + " (由" + modelName + "提供服务)";
    }
    
    private String getFunctionBaseResponse(String functionId, String userMessage) {
        switch (functionId) {
            // 工作提效类功能 - 使用通义千问
            case "meeting_summary":
                return "会议纪要生成助手：我为您智能整理了会议内容并生成了详细纪要：" + userMessage;
            case "professional_translate":
                return "专业翻译助手：我为您提供了多语言精准翻译服务：" + userMessage;
            case "daily_report":
                return "日报处理助手：我为您自动生成了工作日报总结：" + userMessage;
            case "ppt_assistant":
                return "PPT助手：我为您智能制作了演示文稿内容：" + userMessage;
            case "boss_reply":
                return "回复老板神器：我为您提供了职场沟通回复建议：" + userMessage;
                
            // 社媒创作类功能 - 使用豆包
            case "short_video_script":
                return "短视频文案生成：我为您创作了吸引眼球的短视频文案：" + userMessage;
            case "live_streaming_talk":
                return "直播带货话术：我为您提供了专业直播销售话术指导：" + userMessage;
            case "wechat_moments":
                return "朋友圈文案创作：我为您创作了个性化朋友圈内容：" + userMessage;
            case "poster_copy":
                return "海报文案设计：我为您策划了营销海报文案：" + userMessage;
            case "xiaohongshu_copy":
                return "小红书文案：我为您创作了小红书种草文案：" + userMessage;
                
            // 个人助理类功能 - 使用通义千问
            case "travel_guide":
                return "旅游指南：我为您规划了个性化旅游路线：" + userMessage;
            case "food_recommendation":
                return "美食推荐：我为您推荐了本地特色美食：" + userMessage;
            case "study_plan":
                return "学习计划制定：我为您制定了科学高效的学习计划：" + userMessage;
            case "ai_doctor":
                return "AI医生：我为您提供了健康咨询和建议服务：" + userMessage;
            case "legal_consultation":
                return "法律咨询：我为您提供了法律问题解答指导：" + userMessage;
                
            // 生活娱乐类功能 - 使用豆包
            case "story_creation":
                return "故事创作：我为您创作了原创故事情节：" + userMessage;
            case "poetry_generation":
                return "诗歌生成：我为您创作了优美诗歌：" + userMessage;
            case "jokes_and_sketches":
                return "笑话/段子：我为您生成了幽默笑话段子：" + userMessage;
            case "horoscope":
                return "星座运势：我为您解读了每日星座运势：" + userMessage;
            case "weather_query":
                return "天气查询：我为您提供了实时天气信息：" + userMessage;
            case "news_consultation":
                return "新闻咨询：我为您推送了热点新闻资讯：" + userMessage;
            case "stock_query":
                return "股票查询：我为您提供了股市行情实时查询：" + userMessage;
            case "novel_creation":
                return "小说创作：我为您创作了长篇小说情节：" + userMessage;
            case "music_recommendation":
                return "音乐推荐：我为您提供了个性化音乐推荐：" + userMessage;
                
            // 论文辅助类功能 - 使用DeepSeek
            case "paper_outline":
                return "论文大纲生成：我为您设计了学术论文结构大纲：" + userMessage;
            case "reference_organize":
                return "参考文献整理：我为您进行了规范化文献引用整理：" + userMessage;
            case "academic_terms":
                return "学术术语解释：我为您详细解释了专业术语：" + userMessage;
            case "paper_polish":
                return "论文润色：我为您进行了学术写作语言优化：" + userMessage;
                
            // 视频创作类功能 - 使用豆包
            case "short_video_script_detail":
                return "短视频脚本：我为您创作了创意短视频剧本：" + userMessage;
            case "storyboard_design":
                return "分镜脚本设计：我为您设计了专业分镜头脚本：" + userMessage;
            case "dialogue_generation":
                return "台词生成：我为您创作了影视台词：" + userMessage;
            case "background_music_recommend":
                return "背景音乐推荐：我为您提供了视频配乐选择建议：" + userMessage;
                
            // 商业营销类功能 - 使用DeepSeek
            case "product_copy":
                return "产品文案：我为您策划了产品卖点文案：" + userMessage;
            case "marketing_plan":
                return "营销策划案：我为您制定了全方位营销方案：" + userMessage;
            case "advertising_slogan":
                return "广告语创作：我为您创作了朗朗上口的广告语：" + userMessage;
            case "competitor_analysis":
                return "竞品分析报告：我为您提供了深度竞品分析报告：" + userMessage;
                
            // MJ绘画咒语功能 - 使用豆包
            case "ai_painting_prompt":
                return "AI绘画提示词生成：我为您生成了专业AI绘画提示词：" + userMessage;
            case "art_style_recommend":
                return "艺术风格推荐：我为您推荐了多样化艺术风格：" + userMessage;
            case "painting_param_optimize":
                return "绘画参数优化：我为您提供了绘画参数调优建议：" + userMessage;
                
            // 问卷助手功能 - 使用DeepSeek
            case "survey_design":
                return "调查问卷设计：我为您设计了科学问卷结构：" + userMessage;
            case "question_optimize":
                return "问题优化：我为您优化了问卷问题表达：" + userMessage;
            case "survey_data_analysis":
                return "调查数据分析：我为您进行了问卷数据深度分析：" + userMessage;
                
            default:
                return "AI助手：我很乐意为您提供帮助：" + userMessage;
        }
    }
    
    private Integer estimateTokens(String text) {
        return text.length() / 4;
    }
    
    @Override
    public List<AiService.AiModelInfo> getAvailableModels() {
        return Arrays.asList(
            new AiService.AiModelInfo("gpt-3.5-turbo", "GPT-3.5 Turbo", "Fast and efficient AI model", true),
            new AiService.AiModelInfo("gpt-4", "GPT-4", "Advanced AI model with better reasoning", true),
            new AiService.AiModelInfo("claude-3", "Claude-3", "Anthropic's advanced AI model", true),
            new AiService.AiModelInfo("gemini-pro", "Gemini Pro", "Google's advanced AI model", true)
        );
    }
    
    @Override
    public boolean isModelAvailable(String modelId) {
        return getAvailableModels().stream()
                .anyMatch(model -> model.getId().equals(modelId) && model.isEnabled());
    }
}